<!-- 首页 -->
<template>
	<view class="container">
		<TopNav title="位置更新"></TopNav>
		<view class="card radius">
			<view class="flex align-center">
				<image src="/static/images/index/location.png" class="width-16 height-16 m-r4" mode=""></image>
				<text class="text-bold f-s14">当前位置</text>
			</view>
			<view class="m-t8">
				<text class="text-bold f-s14">{{address}}</text>
			</view>
			<view class="m-t4">
				<text class="text-gray f-s10">{{locationForm.address}}</text>
			</view>
			<view class="line m-t16"></view>
			<view class="m-t16 flex align-center justify-between">
				<view class="flex align-center" hover-class="pressed" @click="handleChooseLocation" v-if="!autoPosition">
					<text class="text-theme f-s12 m-r2">手动设置</text>
					<image src="/static/images/index/more-2.png" class="width-16 height-16" mode=""></image>
				</view>
				<view v-else>
					
				</view>
				<view class="self-btn width-68 height-32" hover-class="pressed" @click="handleSignIn">
					<text class="f-s14 f-w500">设置</text>
				</view>
			</view>
		</view>
		<view class="card radius m-t10">
			<view class="flex justify-between">
				<text class="text-bold f-s15">服务半径(半径{{radius}}km)</text>
				<!-- <van-stepper v-model="step" /> -->
				<u-number-box v-model="radius" disabledInput :min="1" :max="100" color="#202020" buttonSize="52rpx"
					bgColor="#F0F1F2" @change="handleRadiusChange" @overlimit="handleRadiusOver"></u-number-box>
			</view>
			<view class="map-container">
				<map class="full-width full-height" id="myMap" ref="myMap" :enable-zoom="false" :enable-scroll="false"
					:latitude="center.latitude" :longitude="center.longitude" :circles="circles" :scale="scale">
					<!-- 用于覆盖map组件，解决iOS设置map禁止拖动/缩放无效问题 -->
					<cover-view class="overlay"
						:style="{'background-color':overlayShow?'rgba(0, 0, 0, 0.7)':'rgba(0, 0, 0, 0)'}"></cover-view>
					<cover-image class="cover" src="/static/images/index/markers.png"></cover-image>
				</map>
			</view>
		</view>

		<!-- iOS cover-view对v-if无效，设置display:none使其隐藏 -->
		<cover-view class="overlay-view" :style="{'display':overlayShow?'flex':'none'}">
			<cover-view class="sign-container">
				<cover-view class="sign-icon-container">
					<!-- iOS必须使用cover-view包裹cover-image，否则图片超出部分会被隐藏 -->
					<cover-image :src="`/static/images/index/${signInStatus?'sign-in-success':'sign-in-fail.'}.png`"
						class="width-80 height-80 sign-icon" mode=""></cover-image>
				</cover-view>
				<cover-view class="m-t8 text-bold f-s16 full-width text-center">
					设置成功
				</cover-view>
				<cover-view class="self-btn m-t22 text-bold f-s16 full-width text-center"
					style="width: 400rpx;line-height: 96rpx;" @click="overlayShow = false">
					我知道啦
				</cover-view>
			</cover-view>
		</cover-view>
		<Toast></Toast>
	</view>
</template>

<script>
	import {
		signIn
	} from "@/api/index/set.js"
	import permision from "@/common/permission.js"
	import {mapState} from "vuex"
	export default {
		name: "",
		data() {
			return {
				address: '',
				locationForm: {
					province: '',
					city: '',
					district: '',
					address: '',
					lat: '',
					lng: ''
				},
				overlayShow: false,
				// 签到状态
				signInStatus: true,
				signInForm: {
					radius: '',
					province: ''
				},
				center: {
					latitude: 39.90923,
					longitude: 116.397428
				}, // 默认北京坐标
				circles: [], // 圆形覆盖物
				radius: 20, // 当前半径（千米）
				scale: 14, // 地图缩放级别
				mapContext: null // 地图上下文
			}
		},
		onShow() {
			this.checkPermission()
			this.radius = this.userInfo?.radius ?? 20
			this.autoPosition = this.userInfo?.auto_update ?? 0
		},
		computed: {
			...mapState({
				userInfo: state => state.user.userInfo || {}
			})
		},
		methods: {
			async checkPermission() {
				let status = permision.isIOS ? await permision.requestIOS('location') :
					await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
				if (status === null || status === 1) {
					status = 1;
					this.$nextTick(() => {
						this.initLocation()
					})
				} else if (status === 2) {
					// 定位服务未启用
					this.address = '定位服务未开启'
					this.$toast("定位服务未开启")
				} else {
					this.address = '定位权限未开启'
					uni.showModal({
						title: "提示",
						content: '定位权限未开启，请前往设置打开授权',
						confirmText: '前往设置',
						success(res) {
							if (res.confirm) {
								uni.openAppAuthorizeSetting()
							}
						}
					})
				}
			},
			handleSignIn() {
				this.signInForm.radius = this.radius
				this.signInForm.province = this.locationForm.province
				this.$modal.loading("签到中").then(res => {
					signIn(this.signInForm).then(res => {
						this.$modal.closeLoading()
						let {
							code
						} = res
						this.signInStatus = Boolean(code)
						this.overlayShow = true
						// 更新信息
						this.$store.dispatch('GetInfo')
					}).catch(() => this.$modal.closeLoading())
				})

			},
			handleChooseLocation() {
				uni.chooseLocation({
					success: (res) => {
						for (let i in res) {
							this[i] = res[i];
						}
						let reg = /.+?(省|市|自治区|自治州|县|区)/g;
						let arr = res.address.match(reg);
						let obj = {
							province: '',
							city: '',
							district: '',
							address: '',
							lat: '',
							lng: '',
						}

						let str = res.address.split(arr[arr.length - 1]);
						if (arr.length === 2) {
							obj.province = arr[0];
							obj.city = obj.district = arr[1];
							obj.address = res.name !== '地图位置' ? res.name : str[1];
							obj.lat = res.latitude;
							obj.lng = res.longitude;
							this.address = obj.province + obj.city
						} else {
							obj.province = arr[0];
							obj.city = arr[1];
							obj.district = arr[2];
							obj.address = res.name !== '地图位置' ? res.name : str[1];
							obj.lat = res.latitude;
							obj.lng = res.longitude;
							this.address = obj.province + obj.city + obj.district
						}
						this.center = {
							latitude: obj.lat,
							longitude: obj.lng
						}
						// 更新地图覆盖图形
						this.updateMapObjects()
						for (let i in obj) {
							this.locationForm[i] = obj[i];
						}

					}
				})
			},
			// 初始化定位
			initLocation() {
				uni.getLocation({
					type: 'gcj02',
					geocode: true,
					success: (res) => {
						let {
							address,
							latitude,
							longitude
						} = res;
						let {
							province,
							city,
							district,
							street,
							poiName
						} = address;
						this.address = `${province}${city}${district}`
						this.center = {
							latitude: res.latitude,
							longitude: res.longitude
						};
						this.locationForm = {
							province,
							city,
							district,
							address: street + poiName,
							lat: latitude,
							lng: longitude
						}
						this.updateMapObjects();
					},
					fail: () => {
						// this.updateMapObjects();
						this.address = '定位失败'
					}
				});
			},

			// 更新地图对象
			updateMapObjects() {
				this.circles = [{
					latitude: this.center.latitude,
					longitude: this.center.longitude,
					radius: this.radius * 1000, // 转换为米
					color: '#FE3F59', // 填充色
					fillColor: '#FE3F5911', // 填充色
					strokeWidth: 2, // 描边宽度
					strokeColor: '#FE3F59' // 描边颜色
				}];
				this.adjustMapViewToCircle()

			},
			// 半径超过阈值
			handleRadiusOver(type) {
				if (type === 'minus') {
					this.$toast("最小服务半径1KM")
				}
				if (type === 'plus') {
					this.$toast("最大服务半径100KM")
				}
			},
			// 半径变化处理
			handleRadiusChange(data) {
				if (data.value < 1 || data.value > 100) return

				// 限制输入范围
				this.circles = [{
					latitude: this.center.latitude,
					longitude: this.center.longitude,
					radius: this.radius * 1000, // 转换为米
					color: '#FE3F59', // 填充色
					fillColor: '#FE3F5911', // 填充色
					strokeWidth: 2, // 描边宽度
					strokeColor: '#FE3F59' // 描边颜色
				}]
				this.adjustMapViewToCircle(); // 调整地图视野
			},

			// 调整地图视野以包含圆形
			adjustMapViewToCircle() {
				try {
					// 计算圆形边界点
					const circle = this.circles[0];
					let includePoints = this.calculateCircleBounds(circle.radius, circle.latitude, circle.longitude)
					let obj = {
						centralPoint: [circle.latitude, circle.longitude],
						otherPoint: includePoints
					}
					this.scale = this.furthest(obj)

				} catch (error) {}
			},
			// 计算最合适缩放
			furthest(obj) {
				var EARTH_RADIUS = 6378137.0; //单位M
				var PI = Math.PI;
				// 转为角度
				function getRad(d) {
					return d * PI / 180.0;
				}

				let distance = {
					// 将地球按照圆形计算
					getGreatCircle: function(coordinate1, coordinate2) {
						var lat1 = coordinate1[0] // 纬度
						var lat2 = coordinate2[0]
						var lng1 = coordinate1[1] // 经度
						var lng2 = coordinate2[1]

						var radLat1 = getRad(lat1);
						var radLat2 = getRad(lat2);

						var a = radLat1 - radLat2;
						var b = getRad(lng1) - getRad(lng2);

						var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math
							.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
						s = s * EARTH_RADIUS;
						s = Math.round(s * 10000) / 10000.0;

						return s;
					},
					// 将地球按照椭圆进行计算
					getFlattern: function(coordinate1, coordinate2) {
						var lat1 = coordinate1[0] // 纬度
						var lat2 = coordinate2[0]
						var lng1 = coordinate1[1] // 经度
						var lng2 = coordinate2[1]

						var f = getRad((lat1 + lat2) / 2);
						var g = getRad((lat1 - lat2) / 2);
						var l = getRad((lng1 - lng2) / 2);

						var sg = Math.sin(g);
						var sl = Math.sin(l);
						var sf = Math.sin(f);

						var s, c, w, r, d, h1, h2;
						var a = EARTH_RADIUS;
						var fl = 1 / 298.257;

						sg = sg * sg;
						sl = sl * sl;
						sf = sf * sf;

						s = sg * (1 - sl) + (1 - sf) * sl;
						c = (1 - sg) * (1 - sl) + sf * sl;

						w = Math.atan(Math.sqrt(s / c));
						r = Math.sqrt(s * c) / w;
						d = 2 * w * a;
						h1 = (3 * r - 1) / 2 / c;
						h2 = (3 * r + 1) / 2 / s;

						return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
					}

				}

				// obj包含中心点坐标和其他所有的坐标位置
				// 处理obj传入的参数
				let centralPoint = obj.centralPoint // 中心点
				let otherPoint = obj.otherPoint // 二维数组存放其他坐标点

				// 循环遍历得出距离最远的1个坐标然后*2
				let farthestCoordinate = [] // 当前最远坐标
				let farthestDistance = 0 // 最远距离
				let dis = null // 存储当前距离
				for (let i in otherPoint) {
					let newLocation = []
					newLocation[0] = otherPoint[i].latitude
					newLocation[1] = otherPoint[i].longitude

					dis = distance.getGreatCircle(centralPoint, newLocation)
					if (dis > farthestDistance) {
						farthestDistance = dis
						farthestCoordinate = newLocation
					}
				}

				farthestDistance = farthestDistance / 1000 // 转为km

				// 根据坐标计算出合理的比例尺寸
				let surface = [500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02]

				for (let i in surface) {
					if (farthestDistance > surface[i]) {
						let scale = 5 + Number(i)
						return scale
					}
				}

				return 16
			},
			// 计算圆形边界坐标
			calculateCircleBounds(circleRadius, latitude, longitude) {
				// 地球半径（米）
				const earthRadius = 6378137

				// 将圆心经纬度转换为弧度
				const lat = latitude * Math.PI / 180
				const lng = longitude * Math.PI / 180

				// 计算半径对应的角度（弧度）
				const d = circleRadius / earthRadius

				// 计算四个方向的边界点
				const points = []

				// 0度（正北）
				points.push({
					latitude: latitude + (d * 180 / Math.PI),
					longitude: longitude
				})

				// 90度（正东）
				points.push({
					latitude: latitude,
					longitude: longitude + (d * 180 / Math.PI) / Math.cos(lat)
				})

				// 180度（正南）
				points.push({
					latitude: latitude - (d * 180 / Math.PI),
					longitude: longitude
				})

				// 270度（正西）
				points.push({
					latitude: latitude,
					longitude: longitude - (d * 180 / Math.PI) / Math.cos(lat)
				})

				return points
			},

		}
	}
</script>

<style scoped lang="scss">
	.container {
		padding: 20rpx 24rpx;
		position: relative;

		.card {
			background-color: #fff;
			padding: 32rpx;
		}

		::v-deep .uicon-plus {
			font-size: 32rpx;
			color: #FE3F59 !important;
		}

		::v-deep .uicon-minus {
			font-size: 32rpx;
			color: #FE3F59 !important;
		}

		.map-container {
			width: 620rpx;
			height: 620rpx;
			margin-top: 30rpx;
			position: relative;

			.overlay {
				position: absolute;
				width: 100%;
				height: 100%;
			}

			.cover {
				width: 10px;
				height: 10px;
				z-index: 99;
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%);
			}
		}


	}

	.overlay-view {
		position: absolute;
		top: 0;
		left: 0;
		bottom: 0;
		height: calc(100vh + constant(safe-area-inset-bottom));
		height: calc(100vh + env(safe-area-inset-bottom));
		width: 100vw;
		background-color: rgba(0, 0, 0, 0.7);
		z-index: 99999;
		display: flex;
		justify-content: center;
		align-items: center;
		overflow: visible;

		.sign-container {
			width: 520rpx;
			height: 326rpx;
			background-color: #fff;
			border-radius: 40rpx;
			display: flex;
			flex-direction: column;
			align-items: center;
			overflow: visible;
			.sign-icon-container{
				margin-top: -80rpx;
			}
			
		}
	}
</style>